package com.util;

import com.pojo.CodeFile;
import com.pojo.ColumnInfo;
import com.pojo.TableInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;

public class GenUtil {

    // 模板文件资源路径 eg: /template/Controller.java.vm
    public static List<String> getTemplateFilenames() {
        URL resource = GenUtil.class.getClassLoader().getResource("template");
        if (resource == null)
            throw new RuntimeException("resources下没有模板文件夹template");

        try {
            // eg: D:\Desktop\%e4%bb%a3%e7%a0%81%e7%94%9f%e6%88%90%e5%b7%a5%e5%85%b7\target\classes\template 转为 /D:/Desktop/代码生成工具/target/classes/template
            String filePath = URLDecoder.decode(resource.getPath(), "UTF-8");
            File file = new File(filePath);
            if (!file.exists() || !file.isDirectory())
                return new ArrayList<>(0);

            String[] filenameList = file.list();
            if (filenameList != null) {
                List<String> list = new ArrayList<>();
                for (String filename : filenameList) {
                    list.add("template/" + filename);
                }
                return list;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new ArrayList<>(0);
    }

    // 生成代码
    public static List<CodeFile> generateCode(TableInfo tableInfo, List<ColumnInfo> columns) {
        Properties config = getGenConfig();
        // 表名转换成Java类名
        String tableNewName= tableInfo.getTableName()
                .replaceFirst(config.getProperty("tablePrefix"), "")
                + config.getProperty("tableSuffix");
        String className = columnToJava(tableNewName);
        tableInfo.setClassName(className);
        tableInfo.setClassname(StringUtils.uncapitalize(className));

        // 列信息
        for (ColumnInfo column : columns) {
            // 列名转换成Java属性名
            String attrName = columnToJava(column.getColumnName());
            column.setAttrName(attrName);
            column.setAttrname(StringUtils.uncapitalize(attrName));
            //列的数据类型，转换成Java类型
            String attrType = config.getProperty(column.getDataType(), columnToJava(column.getDataType()));
            column.setAttrType(attrType);

            // 是否主键
            if ("PRI".equalsIgnoreCase(column.getColumnKey()) && tableInfo.getPrimaryKey() == null) {
                tableInfo.setPrimaryKey(column);
            }
        }
        tableInfo.setColumns(columns);
        System.out.println(columns);
        System.out.println(tableInfo);

        // 设置velocity资源加载器
        Properties prop = new Properties();
        prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        Velocity.init(prop);
        // 封装模板数据
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("tableName", tableInfo.getTableName()); // 表名
        dataMap.put("comments", tableInfo.getTableComment());
        dataMap.put("primaryKey", tableInfo.getPrimaryKey());
        dataMap.put("className", tableInfo.getClassName()); // 开头大写类名 eg: SysUserController
        dataMap.put("classname", tableInfo.getClassname()); // 开头小写类名 eg: sysUserController
        dataMap.put("pathName", tableInfo.getClassname());
        dataMap.put("columns", tableInfo.getColumns());
        dataMap.put("mainPath", config.getProperty("mainPath"));
        dataMap.put("package", config.getProperty("package"));
        dataMap.put("moduleName", config.getProperty("moduleName"));
        VelocityContext context = new VelocityContext(dataMap); // 上下文

        // 获取模板列表
        List<String> templates = getTemplateFilenames();
        List<CodeFile> list = new ArrayList<>(templates.size());
        for (String templateName : templates) {
            // 渲染模板
            StringWriter stringWriter = new StringWriter();
            Template template = Velocity.getTemplate(templateName, "UTF-8");
            template.merge(context, stringWriter);

            CodeFile codeFile = new CodeFile();
            codeFile.filename = tableInfo.getClassName() + templateName.replace("template/", "").replace(".vm", "");
            codeFile.code = stringWriter.toString();
            list.add(codeFile);
        }
        return list;
    }

    // 获取代码生成相关配置
    public static Properties getGenConfig() {
        Properties properties = new Properties();
        try {
            properties.load(GenUtil.class.getClassLoader().getResourceAsStream("generator.yml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return properties;
    }


    // 列名转换成Java类名 eg: role_permission -> RolePermission
    public static String columnToJava(String columnName) {
        return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "");
    }

}
